// Package classification User API.
//
// The purpose of this service is to provide an application
// that is using plain go code to define an API
//
//      Host: localhost
//      Version: 0.0.1
//
// swagger:meta
package demo

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/load"
	"github.com/shirou/gopsutil/mem"
)

const (
	B  = 1
	KB = 1024 * B
	MB = 1024 * KB
	GB = 1024 * MB
)

/**
 * @api {GET} /api/v1/demo/health 健康检查
 * @apiVersion 1.0.0
 * @apiName  health
 * @apiGroup  demo
 * @apiDescription 测试的接口，会输出一个hello world
 * @apiExample {curl} Example usage:
 * curl -i http://127.0.0.1:9090/api/v1/demo/health
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *
 *     "OK"
 */
func HealthCheck(c *gin.Context) {
	message := "OK"
	c.String(http.StatusOK, "\n"+message)
}

/**
 * @api {GET} /api/v1/demo/disk disk示例
 * @apiVersion 1.0.0
 * @apiName  health
 * @apiGroup  demo
 * @apiDescription 测试的接口，会输出一个磁盘使用情况
 * @apiExample {curl} Example usage:
 * curl -i http://127.0.0.1:9090/api/v1/demo/disk
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *
 *     OK - Free space: 104762MB (102GB) / 239172MB (233GB) | Used: 44%
 */
func DiskCheck(c *gin.Context) {
	u, _ := disk.Usage("/")

	usedMB := int(u.Used) / MB
	usedGB := int(u.Used) / GB
	totalMB := int(u.Total) / MB
	totalGB := int(u.Total) / GB
	usedPercent := int(u.UsedPercent)

	status := http.StatusOK
	text := "OK"

	if usedPercent >= 95 {
		status = http.StatusOK
		text = "CRITICAL"
	} else if usedPercent >= 90 {
		status = http.StatusTooManyRequests
		text = "WARNING"
	}

	message := fmt.Sprintf("%s - Free space: %dMB (%dGB) / %dMB (%dGB) | Used: %d%%", text, usedMB, usedGB, totalMB, totalGB, usedPercent)
	c.String(status, "\n"+message)
}

/**
 * @api {GET} /api/v1/demo/cpu cpu示例
 * @apiVersion 1.0.0
 * @apiName  health
 * @apiGroup  demo
 * @apiDescription 测试的接口，会输出一个cpu使用情况
 * @apiExample {curl} Example usage:
 * curl -i http://127.0.0.1:9090/api/v1/demo/cpu
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *
 *     WARNING - Load average: 2.37, 2.26, 2.20 | Cores: 4
 */
func CPUCheck(c *gin.Context) {
	cores, _ := cpu.Counts(false)

	a, _ := load.Avg()
	l1 := a.Load1
	l5 := a.Load5
	l15 := a.Load15

	status := http.StatusOK
	text := "OK"

	if l5 >= float64(cores-1) {
		status = http.StatusInternalServerError
		text = "CRITICAL"
	} else if l5 >= float64(cores-2) {
		status = http.StatusTooManyRequests
		text = "WARNING"
	}

	message := fmt.Sprintf("%s - Load average: %.2f, %.2f, %.2f | Cores: %d", text, l1, l5, l15, cores)
	c.String(status, "\n"+message)
}

/**
 * @api {GET} /api/v1/demo/ram ram示例
 * @apiVersion 1.0.0
 * @apiName  health
 * @apiGroup  demo
 * @apiDescription 测试的接口，会输出一个ram使用情况
 * @apiExample {curl} Example usage:
 * curl -i http://127.0.0.1:9090/api/v1/demo/ram
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *
 *     OK - Free space: 10775MB (10GB) / 16384MB (16GB) | Used: 65%
 */
func RAMCheck(c *gin.Context) {
	u, _ := mem.VirtualMemory()

	usedMB := int(u.Used) / MB
	usedGB := int(u.Used) / GB
	totalMB := int(u.Total) / MB
	totalGB := int(u.Total) / GB
	usedPercent := int(u.UsedPercent)

	status := http.StatusOK
	text := "OK"

	if usedPercent >= 95 {
		status = http.StatusInternalServerError
		text = "CRITICAL"
	} else if usedPercent >= 90 {
		status = http.StatusTooManyRequests
		text = "WARNING"
	}

	message := fmt.Sprintf("%s - Free space: %dMB (%dGB) / %dMB (%dGB) | Used: %d%%", text, usedMB, usedGB, totalMB, totalGB, usedPercent)
	c.String(status, "\n"+message)
}
